package org.ctstudio.extensions

/**
 * 双精浮点数组扩展
 */

/**
 * 断言传入数组与当前数据具有相同长度
 */
fun DoubleArray.assertSameSize(another: DoubleArray) {
    if (this.size != another.size) {
        throw AssertionError("Size mismatch: a[${this.size}], b[${another.size}]")
    }
}

/**
 * 对数据元素进行迭代赋值
 */
fun DoubleArray.assignEach(assign: (index: Int, item: Double) -> Double): DoubleArray {
    for (i in this.indices) {
        this[i] = assign(i, this[i])
    }
    return this
}

/**
 * double[]+double[]，对两个数组元素进行+操作
 */
operator fun DoubleArray.plus(another: DoubleArray): DoubleArray {
    assertSameSize(another)
    return DoubleArray(this.size) { i -> this[i] + another[i] }
}

/**
 * double[]-double[]，对两个数组元素进行-操作
 */
operator fun DoubleArray.minus(another: DoubleArray): DoubleArray {
    assertSameSize(another)
    return DoubleArray(this.size) { i -> this[i] - another[i] }
}

/**
 * double[]*double[]，对两个数组元素进行*操作
 */
operator fun DoubleArray.times(another: DoubleArray): DoubleArray {
    assertSameSize(another)
    return DoubleArray(this.size) { i -> this[i] * another[i] }
}

/**
 * double[]/double[]，对两个数组元素进行-操作
 */
operator fun DoubleArray.div(another: DoubleArray): DoubleArray {
    assertSameSize(another)
    return DoubleArray(this.size) { i -> this[i] / another[i] }
}

/**
 * double[]/double，对数组元素除以一个浮点数
 */
operator fun DoubleArray.div(value: Double): DoubleArray {
    return DoubleArray(this.size) { i -> this[i] / value }
}

/**
 * double[]+=double[]，当前数组元素逐个进行+=操作
 */
operator fun DoubleArray.plusAssign(another: DoubleArray) {
    assertSameSize(another)
    this.forEachIndexed { index, _ -> this[index] += another[index] }
}

/**
 * double[]-=double[]，当前数组元素逐个进行-=操作
 */
operator fun DoubleArray.minusAssign(another: DoubleArray) {
    assertSameSize(another)
    this.forEachIndexed { index, _ -> this[index] -= another[index] }
}

/**
 * double[]*=double[]，当前数组元素逐个进行*=操作
 */
operator fun DoubleArray.timesAssign(other: DoubleArray) {
    assertSameSize(other)
    for (i in this.indices) {
        this[i] *= other[i]
    }
}

/**
 * double[]*=double，当前数组元素逐个*=另一个数
 */
operator fun DoubleArray.timesAssign(value: Double) {
    for (i in this.indices) {
        this[i] *= value
    }
}

/**
 * double[]/=double[]，当前数组元素逐个进行/=操作
 */
operator fun DoubleArray.divAssign(another: DoubleArray) {
    assertSameSize(another)
    this.forEachIndexed { index, _ -> this[index] /= another[index] }
}

/**
 * double[]/=double，当前数组元素逐个/=另一个数
 */
operator fun DoubleArray.divAssign(value: Double) {
    this.forEachIndexed { index, _ -> this[index] /= value }
}